import logging
import heapq

from coin.strategy.mm.calculator import MovingSum


class AmplitudeChecker(object):
  def __init__(self, product, window_min, threshold_bp):
    self._product = product
    self._price_required = 10
    assert window_min > 0, window_min
    self._price_history = MovingSum(window_min * 60e9)
    assert threshold_bp >= 0, threshold_bp
    self._threshold = threshold_bp / 10.**4
    self._alarm = False
    self._logger = logging.getLogger('AmplitudeChecker')

  @property
  def alarm(self):
    return self._alarm

  def _set_alarm(self):
    if not self._alarm:
      self._alarm = True
      self._logger.info('Amplitude alarm set. %s' % self._product)

  def _reset_alarm(self):
    if self._alarm:
      self._alarm = False
      self._logger.info('Amplitude alarm reset. %s' % self._product)

  def on_book(self, product, book):
    assert product == self._product, (product, self._product)
    if not (book.has_bid() and book.has_ask()):
      return
    book_ts = book.timestamp
    mid_price = (book.bid0().price + book.ask0().price) / 2
    self._price_history.update(book_ts, mid_price)

  def update_alarm(self):
    if len(self._price_history) < self._price_required:
      self._reset_alarm()
    else:
      price = [elem[1] for elem in self._price_history._deque]
      heapq.heapify(price)
      min_price = heapq.nsmallest(1, price)[0]
      max_price = heapq.nlargest(1, price)[0]
      amplitude = max_price / min_price - 1
      self._logger.info('min_price: %s' % min_price)
      self._logger.info('max_price: %s' % max_price)
      self._logger.info('amplitude: %s' % amplitude)
      if amplitude >= self._threshold:
        self._set_alarm()
      elif amplitude <= 0.5 * self._threshold:
        self._reset_alarm()
      else:
        pass
